package services;

import bean.Params;
import frame.service.anno.*;
import frame.service.standard.Constants;
import frame.service.standard.MiayCommonRequestParams;
import frame.service.standard.MiayRuntimeException;
import frame.service.util.FrameUtil;
import http.RedisSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import util.SecurityUtil;

/**
 * 会话、会话密钥初始化
 * https://127.0.0.1:9088/miay/open/common/sec/init-1.0.0
 * */
@MiayService(module = "common", service = "sec", safeMode = Constants.SAFE_MODE_OPEN)
public class CommonService {
    private Logger logger = LoggerFactory.getLogger(CommonService.class);

    private Params params;

    public static class Request extends MiayCommonRequestParams{
        private String secret;
        private String clientHello;
        public Request(){}

        public String getSecret() {
            return secret;
        }

        @MiayActionParam(use = "rsa加密的会话密钥", comment = "ras(sessionSecret)")
        public void setSecret(String secret) {
            this.secret = secret;
        }

        public String getClientHello() {
            return clientHello;
        }

        @MiayActionParam(value = "client_hello", use = "会话密钥交换握手信息", comment = "aes(helloMsg|sha256(helloMsg+sessionSecret))")
        public void setClientHello(String clientHello) {
            this.clientHello = clientHello;
        }
    }

    public static class Response{
        private String serverHi;

        public String getServerHi() {
            return serverHi;
        }

        @MiayActionParam(value = "server_hi", use = "会话密钥交换响应", comment = "server_hi=aes(sha256(sessionKey+sessionSecret))")
        public void setServerHi(String serverHi) {
            this.serverHi = serverHi;
        }
    }

    @MiayAction(comment = "前端、后台会话密钥交换接口")
    @MiayActionRequest(Request.class)
    @MiayActionResponse(Response.class)
    @ActionThrows({"930001"})
    public Response init(Request request){
        Response response = new Response();
        //解密获取会话密钥
        byte[] secrets = SecurityUtil.rsaPkcs1Decrypt(params.getSecureParams(Params.Constants.PRIVATE_KEY), request.getSecret());
        String sessionSecret = new String(secrets);
        //解密握手信息，检查握手信息是否正确
        String client_hello = SecurityUtil.aesCbcP7Decrypt(sessionSecret, sessionSecret, SecurityUtil.base64Decode(request.getClientHello()));
        String[] helloMsg = client_hello.split("\\|");
        String mac = SecurityUtil.sha256((helloMsg[0]+sessionSecret).getBytes());
        if(mac.equals(helloMsg[1])){
            //内部会话id
            String sessionUUID = FrameUtil.generateSessionUUID();
            //对外会话id,redis 会话管理key
            String sessionKey = FrameUtil.generateSessionId(sessionUUID,sessionSecret);
            RedisSession redisSession = new RedisSession(sessionKey, sessionUUID, sessionSecret, helloMsg[0]);
            logger.info("Communication key exchange was made successfully.");
            //server_hi 响应：aes(sessionKey|sha256(sessionKey+sessionSecret))
            String serverHiMac = SecurityUtil.sha256((sessionKey + sessionSecret).getBytes());
            String serverHi = sessionKey;
            response.setServerHi(SecurityUtil.aesCbcP7Encrypt(sessionSecret, sessionSecret, serverHi+"|"+serverHiMac));
        }else{
            throw new MiayRuntimeException("930001");
        }
        return response;
    }

    @Autowired
    public void setParams(Params params) {
        this.params = params;
    }
}
